﻿using System;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;

namespace ExpressesClass.StoApi.Base
{
    public class StoClient
    {
        string appKey;
        string secretKey;
        string resourceCode;

        public StoClient(string appKey, string secretKey, string resourceCode)
        {
            this.appKey = appKey;
            this.secretKey = secretKey;
            this.resourceCode = resourceCode;
        }
        public T execute<T>(StoRequest Request) where T : StoResponse
        {
            byte[] responseArray = null;
            string url = Request.GetUrl();
            using (WebClient webClient = new WebClient())
            {
                NameValueCollection postValues = new NameValueCollection();

                JavaScriptSerializer j = new JavaScriptSerializer();
                string content = j.Serialize(Request);

                string dataDigest = CalculateDigest(content, secretKey);

                string apiName = Request.GetApiName();

                string keyName = Request.GetKeyName();

                postValues.Add("content", content);
                postValues.Add("data_digest", dataDigest);
                postValues.Add("api_name", apiName);
                postValues.Add("from_appkey", appKey);
                postValues.Add("from_code", resourceCode);
                postValues.Add("to_appkey", keyName);
                postValues.Add("to_code", keyName);
                webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                responseArray = webClient.UploadValues(url, "POST", postValues);
            }
            string response = Encoding.UTF8.GetString(responseArray);
            return response == null ? null : (T)Request.makeResponse(response);
        }

        public static string CalculateDigest(string content, string secretKey)
        {
            string toSignContent = content + secretKey;
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.GetEncoding("utf-8").GetBytes(toSignContent);
            byte[] hash = md5.ComputeHash(inputBytes);
            return Convert.ToBase64String(hash);
        }
    }
}
